# src/server/sql_handler.py (创建一个新文件)

import os
from typing import Dict

# 导入你的所有核心组件
from ..compiler.compiler import SQLCompiler
from ..execution.planner import QueryPlanner
from ..catalog.table_manager import TableManager
from ..storage.data_manager import DataManager
from ..catalog.booter import Booter
from ..server.auth_manager import AuthManager


class SQLHandler:
    """
    服务器端的核心SQL处理器。
    负责管理数据库实例、事务，并协调编译和执行。
    """

    def __init__(self, auth_manager: AuthManager):
        print("正在初始化SQL Handler和数据库引擎...")

        # 1. 初始化唯一的数据库实例
        # 注意：路径应该是服务器的工作目录，而不是客户端的
        db_dir = os.path.abspath(os.path.join(os.path.dirname(__file__), '../../db_data'))
        os.makedirs(db_dir, exist_ok=True)
        db_file_path = os.path.join(db_dir, "server_database.db")
        print(f"数据库文件路径: {db_file_path}")

        self.dm = DataManager.create(db_file_path, 1024 * 1024 * 10)  # 10MB buffer
        self.booter = Booter.create(db_file_path)
        self.tbm = TableManager(self.dm, self.booter)

        # 2. 初始化编译器和计划器
        self.compiler = SQLCompiler()
        self.planner = QueryPlanner()


        # 3. 初始化会话和事务管理器
        self.auth_manager = auth_manager
        self.session_to_xid: Dict[str, int] = {}  # 关键：映射 session_id -> xid
        print("SQL Handler 初始化完成。")

    def execute_sql(self, sql: str, session_id: str) -> Dict:
        """
        处理来自服务器的SQL执行请求。
        这是服务器调用的主入口点。
        """
        # 检查用户会话是否有效
        if not self.auth_manager.validate_session(session_id):
            return {"success": False, "error": "无效的会话或会话已过期", "error_code": 401}

        # 统一处理SQL（小写，去除前后空格）
        clean_sql = sql.strip().lower()

        try:
            # --- 步骤A: 直接处理事务控制命令 ---
            if clean_sql == 'begin' or clean_sql == 'begin transaction':
                return self._handle_begin(session_id)

            if clean_sql == 'commit':
                return self._handle_commit(session_id)

            if clean_sql == 'rollback' or clean_sql == 'abort':
                return self._handle_abort(session_id)

            # --- 步骤B: 处理常规SQL语句 ---
            # 检查当前会话是否有正在进行的事务
            # 如果没有，则进入“自动提交”模式
            is_autocommit = False
            if session_id not in self.session_to_xid:
                is_autocommit = True
                self._handle_begin(session_id)

            xid = self.session_to_xid[session_id]

            # 1. 编译
            quads, compile_error = self.compiler.compile(sql)
            if compile_error:
                if is_autocommit: self._handle_abort(session_id)  # 编译失败，回滚自动开启的事务
                return {"success": False, "error": f"编译错误: {compile_error}", "error_code": 400}

            # 2. 计划与执行
            result_data = self.planner.plan_and_execute(self.tbm, xid, quads)

            # 3. 自动提交
            if is_autocommit:
                self._handle_commit(session_id)

            # 4. 格式化结果
            return {
                "success": True,
                "data": self._format_result(result_data)
            }

        except Exception as e:
            # 发生任何错误，如果处于自动提交模式，则回滚
            if 'is_autocommit' in locals() and is_autocommit:
                if session_id in self.session_to_xid:
                    self._handle_abort(session_id)
            return {"success": False, "error": f"执行错误: {str(e)}", "error_code": 500}

    def _handle_begin(self, session_id: str) -> Dict:
        if session_id in self.session_to_xid:
            return {"success": False, "error": "当前会话已存在一个活动的事务", "error_code": 409}

        begin_result = self.tbm.begin()
        self.session_to_xid[session_id] = begin_result['xid']
        print(f"Session {session_id[:8]}... 开始事务, XID: {begin_result['xid']}")
        return {"success": True, "data": {"message": "Transaction started."}}

    def _handle_commit(self, session_id: str) -> Dict:
        if session_id not in self.session_to_xid:
            return {"success": False, "error": "当前会话没有活动的事务可提交", "error_code": 404}

        xid = self.session_to_xid[session_id]
        self.tbm.commit(xid)
        del self.session_to_xid[session_id]
        print(f"Session {session_id[:8]}... 提交事务, XID: {xid}")
        return {"success": True, "data": {"message": "Commit successful."}}

    def _handle_abort(self, session_id: str) -> Dict:
        if session_id not in self.session_to_xid:
            return {"success": False, "error": "当前会话没有活动的事务可回滚", "error_code": 404}

        xid = self.session_to_xid[session_id]
        self.tbm.abort(xid)
        del self.session_to_xid[session_id]
        print(f"Session {session_id[:8]}... 回滚事务, XID: {xid}")
        return {"success": True, "data": {"message": "Abort successful."}}

    def _format_result(self, result_from_tm) -> Dict:
        """将 TableManager 的输出格式化为可JSON序列化的字典"""
        if isinstance(result_from_tm, bytes):
            return {"message": result_from_tm.decode('utf-8')}

        # 假设 select 返回的是字典列表
        if isinstance(result_from_tm, list):
            if not result_from_tm:
                return {"columns": [], "rows": [], "row_count": 0}

            # 确保所有元素都是字典
            if all(isinstance(item, dict) for item in result_from_tm):
                columns = list(result_from_tm[0].keys()) if result_from_tm else []
                return {
                    "columns": columns,
                    "rows": result_from_tm,
                    "row_count": len(result_from_tm)
                }

        return {"message": str(result_from_tm)}
